home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / wasm223.zip / SLEEPER.ASM < prev    next >
Assembly Source File  |  1993-05-04  |  27KB  |  962 lines

  1. ; SLEEPER
  2. ; by Eric Tauck
  3. ;
  4. ; This program is a TSR that automatically disables
  5. ; a VGA adapter after a specified amount of time to
  6. ; prevent screen burn-in.
  7.  
  8.         UNUSED+
  9.         JUMP+
  10.  
  11.         jmp     start           ;jump to entry point
  12.  
  13. ;****************************************
  14. ; Resident Data
  15.  
  16. VER_HI  EQU     1               ;high version number
  17. VER_LO  EQU     30              ;low version number
  18.  
  19. SIGN1   EQU     0534CH          ;first part of signature
  20. SIGN2   EQU     04550H          ;second part of signature
  21.  
  22. BIOSEG  EQU     0040H           ;BIOS data area segment
  23. BIOSHF  EQU     0017H           ;BIOS shift bits
  24. SMASK   EQU     00001111B       ;hot key shift mask
  25. SHIFT   EQU     00001100B       ;hot key shift bits (CONTROL + ALTERNATE)
  26.  
  27. func    DB      ?               ;keyboard function number
  28.  
  29. ;--- VGA registers
  30.  
  31. SEQIDX  EQU     03C4H           ;sequencer index register
  32. SEQDAT  EQU     03C5H           ;sequencer data register
  33. CLKIDX  EQU     1               ;clock mode register index
  34.  
  35. ;--- original interrupt handlers
  36.  
  37. int_09  LABEL   DWORD   ;old interrupt 9
  38.         DW      ?
  39.         DW      ?
  40.  
  41. int_16  LABEL   DWORD   ;old interrupt 16
  42.         DW      ?
  43.         DW      ?
  44.  
  45. int_1C  LABEL   DWORD   ;old interrupt 1C
  46.         DW      ?
  47.         DW      ?
  48.  
  49. int_21  LABEL   DWORD   ;old interrupt 21
  50.         DW      ?
  51.         DW      ?
  52.  
  53. ;--- flags
  54.  
  55. FIXED   EQU     0001H   ;video state fixed
  56. DISPL   EQU     0002H   ;video displayed
  57. FORCE   EQU     0004H   ;forced timeout
  58. flags   DW      0000H   ;current flag settings
  59.  
  60. ;--- timer data
  61.  
  62. ticks   DW      5460    ;count value (5 min * 60 sec/min * 18.2 tic/sec)
  63. timer   DW      ?       ;timer value
  64.  
  65. ;--- resident functions
  66.  
  67. NOTHING EQU     0       ;do nothing
  68. RESET   EQU     1       ;reset timer
  69. SHOW    EQU     2       ;screen on
  70. HIDE    EQU     3       ;screen off
  71. TIME    EQU     4       ;force timeout
  72.  
  73. functab LABEL   WORD                    ;resident function table
  74.         DW      OFFSET dummy
  75.         DW      OFFSET screen_reset
  76.         DW      OFFSET screen_on
  77.         DW      OFFSET screen_off
  78.         DW      OFFSET timeout
  79.  
  80. ;****************************************
  81. ; Resident Code
  82.  
  83. ;========================================
  84. ; Low level control.
  85.  
  86. ;--- reset timer
  87.  
  88. reset_timer PROC    NEAR
  89.         seg     cs
  90.         push    ticks           ;ticks on stack
  91.         seg     cs
  92.         pop     timer           ;load timer
  93.         ret
  94.         ENDP
  95.  
  96. ;--- turn off video
  97.  
  98. video_off PROC    NEAR
  99.         push    ax
  100.         push    dx
  101.         mov     dx, SEQIDX              ;sequencer index register
  102.         mov     al, CLKIDX              ;clock mode register
  103.         out     dx, al                  ;set index
  104.         mov     dx, SEQDAT              ;sequencer data register
  105.         in      al, dx                  ;get data
  106.         or      al, 20H                 ;set screen off bit
  107.         out     dx, al                  ;send data
  108.         seg     cs
  109.         and     flags, NOT DISPL        ;clear flag
  110.         pop     dx
  111.         pop     ax
  112.         ret
  113.         ENDP
  114.  
  115. ;--- turn on video
  116.  
  117. video_on PROC    NEAR
  118.         push    ax
  119.         push    dx
  120.         mov     dx, SEQIDX      ;sequencer index register
  121.         mov     al, CLKIDX      ;clock mode register
  122.         out     dx, al          ;set index
  123.         mov     dx, SEQDAT      ;sequencer data register
  124.         in      al, dx          ;get data
  125.         and     al, NOT 20H     ;clear screen off bit
  126.         out     dx, al          ;send data
  127.         seg     cs
  128.         or      flags, DISPL    ;set flag
  129.         pop     dx
  130.         pop     ax
  131.         ret
  132.         ENDP
  133.  
  134. ;========================================
  135. ; Screen functions.
  136.  
  137. ;--- reset screen timer
  138.  
  139. screen_reset PROC NEAR
  140.         seg     cs
  141.         and     flags, NOT FIXED ;clear fixed flag
  142.         call    reset_timer     ;reset timer
  143.         seg     cs
  144.         test    flags, DISPL    ;check if screen on
  145.         jnz     novon
  146.         call    video_on        ;turn on screen
  147. novon   ret
  148.         ENDP
  149.  
  150. ;--- force timeout
  151.  
  152. timeout PROC NEAR
  153.         seg     cs
  154.         and     flags, NOT FIXED ;clear fixed flag (reset)
  155.         seg     cs
  156.         or      flags, FORCE    ;set forced timeout flag
  157.         seg     cs
  158.         mov     timer, 18       ;set timer to two seconds
  159.         ret
  160.         ENDP
  161.  
  162. ;--- turn screen off
  163.  
  164. screen_off PROC NEAR
  165.         seg     cs
  166.         or      flags, FIXED    ;set fixed flag
  167.         seg     cs
  168.         mov     timer, 0        ;zero timer
  169.         call    video_off       ;turn off screen
  170.         ret
  171.         ENDP
  172.  
  173. ;--- screen on
  174.  
  175. screen_on PROC NEAR
  176.         seg     cs
  177.         or      flags, FIXED    ;set fixed flag
  178.         seg     cs
  179.         mov     timer, 0        ;zero timer
  180.         call    video_on        ;turn on screen
  181.         ret
  182.         ENDP
  183.  
  184. ;--- dummy function
  185.  
  186. dummy   PROC    NEAR
  187.         ret
  188.         ENDP
  189.  
  190. ;--- transfer to screen routine in BX
  191.  
  192. screen_func PROC NEAR
  193.         shl     bx                      ;convert number to offset
  194.         seg     cs
  195.         jmp     WORD [functab + bx]     ;branch to routine
  196.         ENDP
  197.  
  198. ;========================================
  199. ; Interrupt 09H handler.
  200.  
  201. key_han PROC    NEAR
  202.         seg     cs
  203.         test    flags, FIXED OR FORCE   ;check if fixed state or forced timeout
  204.         jnz     kdone
  205.         call    screen_reset    ;reset timer and screen
  206. kdone   seg     cs
  207.         jmp     int_09          ;branch to old keyboard handler
  208.         ENDP
  209.  
  210. ;========================================
  211. ; Check for a hotkey and pass command
  212. ; to resident sleeper.  NOTE: all the
  213. ; flags except CY are preserved.
  214. ;
  215. ; In: AH= scan code.
  216. ;
  217. ; Out: CY= set if hotkey pressed,
  218. ;      cleared if not.
  219.  
  220. key_check PROC  NEAR
  221.         pushf
  222.         push    ax
  223.         push    bx
  224.  
  225. ;--- check scan code
  226.  
  227.         mov     bx, RESET
  228.         cmp     ah, 19          ;R - reset timer
  229.         je      kshft
  230.         mov     bx, SHOW
  231.         cmp     ah, 47          ;V - visible screen
  232.         je      kshft
  233.         mov     bx, HIDE
  234.         cmp     ah, 35          ;H - hidden screen
  235.         je      kshft
  236.         mov     bx, TIME
  237.         cmp     ah, 20          ;T - force timeout
  238.         je      kshft
  239.  
  240. kcdone  pop     bx
  241.         pop     ax
  242.         popf
  243.         clc
  244.         ret
  245.  
  246. ;--- check shift state
  247.  
  248. kshft   push    ds
  249.         mov     ax, BIOSEG      ;data area segment
  250.         mov     ds, ax
  251.         mov     al, [BIOSHF]    ;load first shift byte
  252.         pop     ds
  253.  
  254.         and     al, SMASK       ;mask bits
  255.         cmp     al, SHIFT       ;check if proper shift
  256.         jne     kcdone          ;exit if not
  257.  
  258. ;--- execute resident function
  259.  
  260.         call    screen_func     ;execute screen function
  261.  
  262.         pop     bx
  263.         pop     ax
  264.         popf
  265.         stc
  266.         ret
  267.         ENDP
  268.  
  269. ;========================================
  270. ; Interrupt 16H handler.
  271.  
  272. key2_han PROC   NEAR
  273.         seg     cs
  274.         mov     func, ah        ;save function number
  275.  
  276.         cmp     ah, 0           ;check if fetch key
  277.         je      k2fet
  278.         cmp     ah, 10H         ;check if fetch extended key
  279.         je      k2fet
  280.         cmp     ah, 1           ;check if keyboard status
  281.         je      k2stat
  282.         cmp     ah, 11H         ;check if extended keyboard status
  283.         je      k2stat
  284.         seg     cs
  285.         jmp     int_16          ;branch to original keyboard handler
  286.  
  287. ;--- fetch keystroke
  288.  
  289. k2fet1  seg     cs
  290.         mov     ah, func        ;load function
  291.  
  292. k2fet   pushf
  293.         seg     cs
  294.         call    int_16          ;call keyboard handler
  295.         call    key_check       ;check for hotkey
  296.         jc      k2fet1          ;loop back if so
  297.  
  298.         iret
  299.  
  300. ;--- keyboard status
  301.  
  302. k2stat1 sub     ah, ah          ;fetch key function
  303.         pushf
  304.         seg     cs
  305.         call    int_16          ;call keyboard handler
  306.         seg     cs
  307.         mov     ah, func        ;reload function
  308.         
  309. k2stat  pushf
  310.         seg     cs
  311.         call    int_16          ;call keyboard handler
  312.         jz      k2e2            ;exit if no key
  313.  
  314.         call    key_check       ;check for hotkey
  315.         jc      k2stat1         ;loop back if so
  316.  
  317. k2e2    retf    2               ;return with flags
  318.         ENDP
  319.  
  320. ;========================================
  321. ; Interrupt 1CH handler.
  322.  
  323. tic_han PROC    NEAR
  324.         seg     cs
  325.         cmp     timer, 0                ;check if timer zero
  326.         je      tdone                   ;done if so
  327.  
  328.         seg     cs
  329.         dec     timer                   ;decrement timer
  330.         jnz     tdone
  331.         call    video_off               ;turn off screen
  332.         seg     cs
  333.         and     flags, NOT FORCE        ;clear forced flag
  334.  
  335. tdone   seg     cs
  336.         jmp     int_1C                  ;branch to old timer handler
  337.         ENDP
  338.  
  339. ;========================================
  340. ; Interrupt 21H handler.
  341.  
  342. dos_han PROC   NEAR
  343.         cmp     ah, 2Bh         ;check set date function
  344.         jne     ddone
  345.         cmp     cx, SIGN1       ;check if first signature matches
  346.         jne     ddone
  347.         cmp     dx, SIGN2       ;check if second signature matches
  348.         jne     ddone
  349.  
  350. ;--- external query
  351.  
  352.         call    screen_func     ;execute screen function in BX
  353.         sub     al, al          ;clear error
  354.         mov     dx, cs          ;return segment
  355.         iret                    ;exit
  356.  
  357. ;--- branch to old DOS
  358.  
  359. ddone   seg     cs
  360.         jmp     int_21          ;branch to dos handler
  361.         ENDP
  362.  
  363. ;========================================
  364. ; End of resident code/data.
  365.  
  366. end_res LABEL  NEAR             ;label marking end
  367.  
  368. ;****************************************
  369. ; Transient Data
  370.  
  371. ENVIRO  EQU    002CH            ;offset of environtment in PSP
  372. COMLINE EQU    0081H            ;start of command line characters
  373.  
  374. ;--- option table
  375.  
  376. OPT_HELP        EQU     0       ;request help
  377. OPT_INSTALL     EQU     1       ;install
  378. OPT_UNINSTALL   EQU     2       ;uninstall
  379. OPT_RESET       EQU     3       ;reset timer
  380. OPT_SHOW        EQU     4       ;force visible
  381. OPT_HIDE        EQU     5       ;force hidden
  382. OPT_TICKS       EQU     6       ;set ticks
  383. OPT_TIMEOUT     EQU     7       ;force timeout
  384.  
  385. opttab  LABEL   WORD                    ;option routine table
  386.         DW      OFFSET help
  387.         DW      OFFSET install
  388.         DW      OFFSET remove
  389.         DW      OFFSET send_reset
  390.         DW      OFFSET send_show
  391.         DW      OFFSET send_hide
  392.         DW      OFFSET send_ticks
  393.         DW      OFFSET send_timeout
  394.  
  395. ;--- messages
  396.  
  397. banner  DB      13,10,'SLEEPER  Version '
  398.         DB      VER_HI+'0', '.', (VER_LO/10)+'0', (VER_LO\10)+'0'
  399.         DB      '  Eric Tauck  10/25/1989',13,10,'$'
  400.  
  401. mes1a   DB      'Sleeper installed with timer = ','$'
  402. mes1b   DB      ' ticks',13,10,'$'
  403. mes2    DB      'Error in options, run "SLEEPER ?" for help',13,10,'$'
  404. mes3    DB      'Cannot uninstall Sleeper',13,10,'$'
  405. mes4    DB      'Sleeper removed from memory',13,10,'$'
  406. mes5    DB      'Sleeper must be installed first',13,10,'$'
  407. mes6    DB      'Sleeper already installed',13,10,'$'
  408. mes7a   DB      'Sleeper reset with timer = ','$'
  409. mes7b   DB      ' ticks',13,10,'$'
  410. mes8    DB      'Sleeper timer reset',13,10,'$'
  411. mes9    DB      'Screen forced visible',13,10,'$'
  412. mes10   DB      'Screen forced hidden',13,10,'$'
  413. mes11   DB      'Forced timeout',13,10,'$'
  414.  
  415. ;--- help message
  416.  
  417. hmes    LABEL   BYTE
  418.   DB 13,10
  419.   DB 'Installation Options:',13,10
  420.   DB 13,10
  421.   DB '  SLEEPER       install with a default timer value of 5 minutes',13,10
  422.   DB '  SLEEPER nnn   install with a timer value of 1 to 3600 seconds',13,10
  423.   DB 13,10
  424.   DB 'Resident Options:',13,10
  425.   DB 13,10
  426.   DB '  SLEEPER v     force visible screen (also when not resident)',13,10
  427.   DB '  SLEEPER h     force hidden screen (also when not resident)',13,10
  428.   DB '  SLEEPER t     force timeout',13,10
  429.   DB '  SLEEPER r     reset timer',13,10
  430.   DB '  SLEEPER nnn   reset timer with a value of 1 to 3600 seconds',13,10
  431.   DB '  SLEEPER u     uninstall',13,10
  432.   DB 13,10
  433.   DB 'Keyboard Commands:',13,10
  434.   DB 13,10
  435.   DB '  ALT-CTL-V     force visible screen',13,10
  436.   DB '  ALT-CTL-H     force hidden screen',13,10
  437.   DB '  ALT-CTL-T     force timeout',13,10
  438.   DB '  ALT-CTL-R     reset timer ',13,10
  439.   DB '$'
  440.  
  441. ;****************************************
  442. ; Transient Code
  443.  
  444. ;========================================
  445. ; Macro to display a $ terminated string
  446.  
  447. display MACRO   str
  448.         mov     ah, 9           ;display function
  449.         mov     dx, OFFSET str  ;load address
  450.         int     21H             ;execute
  451.         ENDM
  452.  
  453. ;========================================
  454. ; Display the number in AX.
  455.  
  456. number  PROC    NEAR
  457.         mov     bx, 10          ;base
  458.         sub     cx, cx          ;digit count
  459.  
  460. ;--- determine decimal digits
  461.  
  462. numeval sub     dx, dx          ;zero for divide
  463.         div     ax, bx          ;divide by base
  464.         push    dx              ;save digit on stack
  465.         inc     cx              ;increment digit count
  466.         or      ax, ax          ;check if anything left
  467.         jnz     numeval         ;loop back if so
  468.  
  469. ;--- display number
  470.  
  471. numdisp pop     dx              ;restore value
  472.         add     dl, '0'         ;convert to ASCII
  473.         mov     ah, 2           ;display function
  474.         int     21H             ;execute
  475.         loop    numdisp         ;loop for each digit
  476.  
  477.         ret
  478.         ENDP
  479.  
  480. ;========================================
  481. ; Call resident sleeper.
  482. ;
  483. ; In: BX= resident command.
  484. ;
  485. ; Out: DX= resident data segment; CY=
  486. ;      set if error (not resident).
  487.  
  488. resident PROC   NEAR
  489.         mov     ah, 2Bh         ;set date function
  490.         mov     cx, SIGN1       ;signature one
  491.         mov     dx, SIGN2       ;signature two
  492.         int     21H             ;execute
  493.         sub     al, 1           ;subtract (use SUB to set CY flag)
  494.         cmc                     ;set carry on error
  495.         ret
  496.         ENDP
  497.  
  498. ;========================================
  499. ; Process command line.
  500. ;
  501. ; Out: BX= option number; CY= set if
  502. ;      error.
  503.  
  504. options PROC    NEAR
  505.         cld
  506.  
  507. ;--- skip delimiters
  508.  
  509.         mov     si, COMLINE     ;start of command line
  510.         mov     bx, OPT_INSTALL
  511.  
  512. skdel   lodsb                   ;load character
  513.         cmp     al, 13          ;check if end of line
  514.         je      optok           ;exit if so
  515.         cmp     al, ' '         ;check if delimiter
  516.         jbe     skdel           ;loop back if so
  517.  
  518. ;--- check for standard options
  519.  
  520.         mov     dl, al          ;save character
  521.         or      al, 20H         ;convert to lower-case
  522.         mov     bx, OPT_RESET
  523.         cmp     al, 'r'
  524.         je      optok
  525.         mov     bx, OPT_SHOW
  526.         cmp     al, 'v'
  527.         je      optok
  528.         mov     bx, OPT_HIDE
  529.         cmp     al, 'h'
  530.         je      optok
  531.         mov     bx, OPT_UNINSTALL
  532.         cmp     al, 'u'
  533.         je      optok
  534.         mov     bx, OPT_HELP
  535.         cmp     al, '?'
  536.         je      optok
  537.         mov     bx, OPT_TIMEOUT
  538.         cmp     al, 't'
  539.         je      optok
  540.  
  541. ;--- convert number
  542.  
  543.         mov     bx, 10          ;base
  544.         sub     cx, cx          ;zero total
  545.         mov     al, dl          ;restore character
  546.  
  547. evall   sub     al, '0'         ;convert to value
  548.         cmp     al, 9           ;check if out of range
  549.         ja      opterr          ;jump if so
  550.  
  551.         sub     ah, ah
  552.         xchg    ax, cx          ;total in AX, digit value in CX
  553.         mul     ax, bx          ;total times base
  554.         add     cx, ax          ;new total
  555.  
  556.         lodsb                   ;load next character
  557.         cmp     al, ' '         ;check if delimiter
  558.         ja      evall           ;loop back if not
  559.  
  560.         mov     ax, 18          ;18/ticks per second
  561.         mul     cx              ;convert
  562.         or      dx, dx          ;check if too big
  563.         jnz     opterr          ;jump if so
  564.         push    ax
  565.         mov     ax, 5           ;plus .2/ticks per sec
  566.         xchg    ax, cx
  567.         div     ax, cx          ;for every 5, add one more
  568.         pop     dx
  569.         add     dx, ax          ;total ticks
  570.         jc      opterr          ;jump if too many
  571.         mov     ticks, dx       ;save ticks
  572.         mov     bx, OPT_TICKS   ;return function
  573.  
  574. ;--- done
  575.  
  576. optok   clc
  577.         ret
  578.  
  579. ;--- error
  580.  
  581. opterr  display mes2    ;show error message
  582.         stc
  583.         ret
  584.         ENDP
  585.  
  586. ;========================================
  587. ; Display help screen.
  588. ;
  589. ; Out: AL= termination code.
  590.  
  591. help    PROC    NEAR
  592.         display hmes    ;display help text
  593.         sub     al, al  ;no error
  594.         ret
  595.         ENDP
  596.  
  597. ;========================================
  598. ; Install in memory.
  599. ;
  600. ; Out: AL= termination code (only if
  601. ;      failure).
  602.  
  603. install PROC    NEAR
  604.  
  605. ;--- check if already installed
  606.  
  607.         mov     bx, NOTHING     ;no resident operation
  608.         call    resident        ;link to resident version
  609.         jc      noierr          ;jump if okay
  610.         display mes6            ;display error message
  611.         mov     al, -1          ;return error code
  612.         ret
  613.  
  614. ;--- start installation
  615.  
  616. noierr  call    reset_timer     ;reset timer
  617.  
  618. ;--- display message
  619.  
  620.         display mes1a           ;first part
  621.         mov     ax, ticks       ;load timer value
  622.         call    number          ;display
  623.         display mes1b           ;second part
  624.  
  625. ;--- save keyboard interrupt 9
  626.  
  627.         mov     ax, 3509H               ;get keyboard interrupt
  628.         int     21H                     ;execute
  629.         mov     WORD int_09, bx         ;save offset
  630.         mov     WORD int_09+2, es       ;save segment
  631.  
  632. ;--- install keyboard interrupt 9
  633.  
  634.         mov     ax, 2509H               ;set keyboard interrupt
  635.         mov     dx, OFFSET key_han      ;keyboard handler
  636.         int     21H                     ;execute
  637.  
  638. ;--- save timer interrupt 1C
  639.  
  640.         mov     ax, 351CH               ;get keyboard interrupt
  641.         int     21H                     ;execute
  642.         mov     WORD int_1C, bx         ;save offset
  643.         mov     WORD int_1C+2, es       ;save segment
  644.  
  645. ;--- install timer interrupt 1C
  646.  
  647.         mov     ax, 251CH               ;set interrupt 1C
  648.         mov     dx, OFFSET tic_han      ;timer tick handler
  649.         int     21H                     ;execute
  650.         call    reset_timer             ;reset timer
  651.  
  652. ;--- save keyboard fetch interrupt 16
  653.  
  654.         mov     ax, 3516H               ;get keyboard interrupt
  655.         int     21H                     ;execute
  656.         mov     WORD int_16, bx         ;save offset
  657.         mov     WORD int_16+2, es       ;save segment
  658.  
  659. ;--- install keyboard fetch interrupt 16
  660.  
  661.         mov     ax, 2516H               ;set interrupt 16
  662.         mov     dx, OFFSET key2_han     ;keyboard fetch handler
  663.         int     21H                     ;execute
  664.  
  665. ;--- save DOS interrupt 21
  666.  
  667.         mov     ax, 3521H               ;get keyboard interrupt
  668.         int     21H                     ;execute
  669.         mov     WORD int_21, bx         ;save offset
  670.         mov     WORD int_21+2, es       ;save segment
  671.  
  672. ;--- install DOS interrupt 21
  673.  
  674.         mov     ax, 2521H               ;set interrupt 21
  675.         mov     dx, OFFSET dos_han      ;DOS handler
  676.         int     21H                     ;execute
  677.  
  678. ;--- install
  679.  
  680.         mov     dx, OFFSET end_res      ;end of resident code
  681.         mov     cl, 4
  682.         shr     dx, cl                  ;convert to paragraph
  683.         inc     dx                      ;round up, paragraphs to reserve
  684.  
  685.         mov     ax, 3100H       ;resident-terminate with exit code 0
  686.         int     21H             ;execute
  687.         ENDP
  688.  
  689. ;========================================
  690. ; Remove from memory.
  691. ;
  692. ; Out: AL= termination code.
  693.  
  694. remove  PROC    NEAR
  695.  
  696. ;--- check if installed
  697.  
  698.         mov     bx, NOTHING     ;no resident operation
  699.         call    resident        ;link to resident version
  700.         jnc     norerr          ;jump if okay
  701.         display mes5            ;display error message
  702.         mov     al, -1          ;return error code
  703.         ret
  704.  
  705. ;--- start removal
  706.  
  707. norerr  push    ds
  708.         mov     ds, dx          ;switch to resident data segment
  709.  
  710. ;=== verify vectors
  711.  
  712.         mov     cx, ds
  713.  
  714. ;--- verify interrupt 9
  715.  
  716.         mov     ax, 3509H               ;get interrupt
  717.         int     21H                     ;execute
  718.         cmp     bx, OFFSET key_han      ;check offset
  719.         jne     verr
  720.         mov     ax, es
  721.         cmp     ax, cx                  ;check segment
  722.         jne     verr
  723.  
  724. ;--- verify interrupt 1C
  725.  
  726.         mov     ax, 351CH               ;get interrupt
  727.         int     21H                     ;execute
  728.         cmp     bx, OFFSET tic_han      ;check offset
  729.         jne     verr
  730.         mov     ax, es
  731.         cmp     ax, cx                  ;check segment
  732.         jne     verr
  733.  
  734. ;--- verify interrupt 16
  735.  
  736.         mov     ax, 3516H               ;get interrupt
  737.         int     21H                     ;execute
  738.         cmp     bx, OFFSET key2_han     ;check offset
  739.         jne     verr
  740.         mov     ax, es
  741.         cmp     ax, cx                  ;check segment
  742.         jne     verr
  743.  
  744. ;--- verify interrupt 21
  745.  
  746.         mov     ax, 3521H               ;get interrupt
  747.         int     21H                     ;execute
  748.         cmp     bx, OFFSET dos_han      ;check offset
  749.         jne     verr
  750.         mov     ax, es
  751.         cmp     ax, cx                  ;check segment
  752.         jne     verr
  753.         jmps    unhook
  754.  
  755. ;--- error
  756.  
  757. verr    pop     ds
  758.         display mes3            ;display message
  759.         mov     al, -1          ;error code
  760.         ret
  761.  
  762. ;=== unhook interrupts
  763.  
  764. unhook  push    ds              ;save resident segment
  765.         push    ds
  766.         pop     es              ;transfer resident segment to ES
  767.  
  768. ;--- unhook 9
  769.  
  770.         mov     ax, 2509H               ;set interrupt function
  771.         seg     es
  772.         mov     dx, WORD int_09         ;offset
  773.         seg     es
  774.         mov     ds, WORD int_09+2       ;segment
  775.         int     21H                     ;execute
  776.  
  777. ;--- unhook 16
  778.  
  779.         mov     ax, 2516H               ;set interrupt function
  780.         seg     es
  781.         mov     dx, WORD int_16         ;offset
  782.         seg     es
  783.         mov     ds, WORD int_16+2       ;segment
  784.         int     21H                     ;execute
  785.  
  786. ;--- unhook 1C
  787.  
  788.         mov     ax, 251CH               ;set interrupt function
  789.         seg     es
  790.         mov     dx, WORD int_1C         ;offset
  791.         seg     es
  792.         mov     ds, WORD int_1C+2       ;segment
  793.         int     21H                     ;execute
  794.  
  795. ;--- unhook 21
  796.  
  797.         mov     ax, 2521H               ;set interrupt function
  798.         seg     es
  799.         mov     dx, WORD int_21         ;offset
  800.         seg     es
  801.         mov     ds, WORD int_21+2       ;segment
  802.         int     21H                     ;execute
  803.  
  804.         pop     ds              ;restore resident segment
  805.  
  806. ;=== release memory
  807.  
  808. ;--- release environment
  809.  
  810.         mov     ax, [ENVIRO]    ;load environment segment
  811.         or      ax, ax          ;check if any
  812.         jz      noenv
  813.         mov     es, ax
  814.         mov     ah, 49H         ;release memory function
  815.         int     21H             ;execute
  816.  
  817. ;--- release code
  818.  
  819. noenv   push    ds
  820.         pop     es
  821.         mov     ah, 49H         ;release memory function
  822.         int     21H             ;execute
  823.  
  824.         pop     ds              ;restore local DS
  825.  
  826.         display mes4            ;display message
  827.         sub     al, al          ;no error
  828.         ret
  829.         ENDP
  830.  
  831. ;========================================
  832. ; Reset resident sleeper.
  833.  
  834. send_reset PROC NEAR
  835.         mov     bx, RESET       ;command
  836.         call    resident        ;send to resident sleeper
  837.         jc      sreserr
  838.  
  839. ;--- success
  840.  
  841.         display mes8            ;message
  842.         mov     al, 0           ;no error
  843.         ret
  844.  
  845. ;--- error
  846.  
  847. sreserr display mes5            ;error message
  848.         mov     al, -1          ;error code
  849.         ret
  850.         ENDP
  851.  
  852. ;========================================
  853. ; Force a timeout.
  854.  
  855. send_timeout PROC NEAR
  856.         mov     bx, TIME        ;command
  857.         call    resident        ;send to resident sleeper
  858.         jc      stimerr
  859.  
  860. ;--- success
  861.  
  862.         display mes11           ;message
  863.         mov     al, 0           ;no error
  864.         ret
  865.  
  866. ;--- error
  867.  
  868. stimerr display mes5            ;error message
  869.         mov     al, -1          ;error code
  870.         ret
  871.         ENDP
  872.  
  873. ;========================================
  874. ; Show screen.
  875.  
  876. send_show PROC NEAR
  877.         mov     bx, SHOW        ;command
  878.         call    resident        ;send to resident sleeper
  879.         jnc     sshook
  880.  
  881. ;--- turn on screen
  882.  
  883.         call    video_on        ;turn on video
  884.  
  885. ;--- done
  886.  
  887. sshook  display mes9            ;message
  888.         mov     al, 0           ;no error
  889.         ret
  890.         ENDP
  891.  
  892. ;========================================
  893. ; Hide screen.
  894.  
  895. send_hide PROC NEAR
  896.         mov     bx, HIDE        ;command
  897.         call    resident        ;send to resident sleeper
  898.         jnc     shidok
  899.  
  900. ;--- turn off screen
  901.  
  902.         call    video_off       ;turn off video
  903.  
  904. ;--- done
  905.  
  906. shidok  display mes10           ;message
  907.         mov     al, 0           ;no error
  908.         ret
  909.         ENDP
  910.  
  911. ;========================================
  912. ; Set number of ticks in resident
  913. ; sleeper.
  914.  
  915. send_ticks PROC NEAR
  916.  
  917. ;--- check if installed
  918.  
  919.         mov     bx, NOTHING     ;no resident operation
  920.         call    resident        ;link to resident version
  921.         jc      ticerr          ;jump if not installed
  922.  
  923. ;--- modify resident sleeper
  924.  
  925.         mov     ax, ticks       ;load local tick count
  926.         push    ds
  927.         mov     ds, dx          ;switch to resident segment
  928.         mov     ticks, ax       ;set new tick count
  929.         pop     ds
  930.         mov     bx, RESET       ;command
  931.         call    resident        ;send to resident sleeper
  932.  
  933. ;--- display message
  934.  
  935.         display mes7a           ;first part
  936.         mov     ax, ticks       ;load timer value
  937.         call    number          ;display
  938.         display mes7b           ;second part
  939.  
  940.         mov     al, 0           ;no error
  941.         ret
  942.  
  943. ;--- goto install
  944.  
  945. ticerr  jmp     install         ;goto install
  946.         ENDP
  947.  
  948. ;****************************************
  949. ; Program entry point.
  950.  
  951. start   display banner                  ;display banner
  952.         call    options                 ;parse command line
  953.         mov     al, -1                  ;error code if parameter error
  954.         jc      term                    ;jump if error
  955.         shl     bx                      ;adjust option number to offset
  956.         call    WORD [opttab + bx]      ;call option routine
  957.  
  958. ;--- terminate, result code in AL
  959.  
  960. term    mov     ah, 4CH         ;exit function
  961.         int     21H             ;execute
  962.